package com.fangmu.transferdata;

import androidx.appcompat.app.AppCompatActivity;

import android.hardware.usb.UsbDevice;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

import com.fangmu.transferdata.databinding.ActivityMainBinding;
import com.fangmu.transferdata.utils.BytesUtils;
import com.fangmu.transferdata.utils.ReadFile;
import com.fangmu.transferdata.utils.USBBroadCastReceiver;
import com.fangmu.transferdata.utils.UsbHelper;
import com.github.mjdev.libaums.UsbMassStorageDevice;
import com.github.mjdev.libaums.fs.UsbFile;
import com.github.mjdev.libaums.fs.UsbFileInputStream;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;

import me.f1reking.serialportlib.SerialPortHelper;
import me.f1reking.serialportlib.listener.ISerialPortDataListener;

public class MainActivity extends AppCompatActivity implements USBBroadCastReceiver.UsbListener, MainConstract.View {

    private static final String TAG = "MainActivity";
    private ActivityMainBinding binding;
    private MainPresenter mPresenter;
    private UsbHelper mUsbHelper;
    private SerialPortHelper mPortHelper;
    private InputStream is;
    private int fileLength;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
        //初始化
        mPresenter = new MainPresenter(this, this);
        mUsbHelper = new UsbHelper(this, this);
        initView();
    }

    private void initView() {
        binding.btnReadU.setOnClickListener(view -> {
            UsbMassStorageDevice[] deviceList = mUsbHelper.getDeviceList();
            mPresenter.getUDiskList(deviceList, mUsbHelper);
        });

        binding.btnOpen.setOnClickListener(view -> {
            mPortHelper = new SerialPortHelper();
            mPortHelper.setPort("/dev/ttyS3");
            mPortHelper.setBaudRate(115200);
//            mPortHelper.setISerialPortDataListener(this);
            mPortHelper.open();
            Toast.makeText(this, "已经设置好串口", Toast.LENGTH_SHORT).show();
        });

        binding.btnSend.setOnClickListener(view -> {
            informIntent("EB90A0010D0A");
            //shakeHands("EB90B0010D0A");
        });

        binding.btnClose.setOnClickListener(view -> {
            mPortHelper.close();
        });
    }

    /**
     * 1.通知下位机跳转到底层
     * @param hex  EB90A0010D0A
     * @return  EB90A001FF0D0A
     */
    private void informIntent(String hex) {
        mPortHelper.sendHex(hex);
        Log.d(TAG, "informIntent: 通知下位机跳转到底层" + hex);
        mPortHelper.setISerialPortDataListener(new ISerialPortDataListener() {
            @Override
            public void onDataReceived(byte[] bytes) {
                String intentData = BytesUtils.ByteArrToHex(bytes);
                Log.d(TAG, "informIntent: 接收数据" + intentData);
                if (intentData.equals("EB90A001FF0D0A")) {
                    Log.d(TAG, "informIntent: 下位机跳转成功，开始握手");
                    shakeHands("EB90B0010D0A");
                }else {
                    Log.e(TAG, "informIntent: 下位机跳转失败");
                }
            }

            @Override
            public void onDataSend(byte[] bytes) {

            }
        });
    }

    /**
     * 2.与下位机握手
     * @param hex EB90B0010D0A
     * @return EB906AA6FF0D0A
     */
    private void shakeHands(String hex) {
        mPortHelper.sendHex(hex);
        Log.d(TAG, "shakeHands: 向下位机发送数据" + hex);
        mPortHelper.setISerialPortDataListener(new ISerialPortDataListener() {
            @Override
            public void onDataReceived(byte[] bytes) {
                String shakeHands = BytesUtils.ByteArrToHex(bytes);
                Log.d(TAG, "shakeHands: 握手接收返回数据" + shakeHands);
                if (shakeHands.equals("EB906AA6FF0D0A")) {
                    Log.d(TAG, "shakeHands: 握手成功，通知下位机擦除数据");
                    eraseData("EB90B0020D0A");
                }else {
                    Log.e(TAG, "shakeHands: 握手失败");
                }
            }

            @Override
            public void onDataSend(byte[] bytes) {

            }
        });
    }

    /**
     * 3.通知下位机擦除数据
     * @param hex EB90B0020D0A
     * @return EB90B002FF0D0A
     */
    private void eraseData(String hex) {
        mPortHelper.sendHex(hex);
        mPortHelper.setISerialPortDataListener(new ISerialPortDataListener() {
            @Override
            public void onDataReceived(byte[] bytes) {
                String shakeHands = BytesUtils.ByteArrToHex(bytes);
                Log.d(TAG, "eraseData: 擦除接收返回数据" + shakeHands);
                if (shakeHands.equals("EB90B002FF0D0A")) {
                    Log.d(TAG, "eraseData: 擦除成功，发送文件大小");
                    sendFileSize("EB90B003");
                }else {
                    Log.e(TAG, "eraseData: 擦除失败");
                }
            }

            @Override
            public void onDataSend(byte[] bytes) {

            }
        });
    }

    /**
     * 4.向下位机发送文件大小 32796
     * @param hex EB90B003 XX,XX,XX,XX
     * @return EB90B003FF0D0A
     */
    private void sendFileSize(String hex) {
        String s = BytesUtils.IntToHex(fileLength);
        Log.d(TAG, "sendFileSize: 十六进制的文件大小" + s);
        mPortHelper.sendHex(hex+"0000"+s);
        mPortHelper.setISerialPortDataListener(new ISerialPortDataListener() {
            @Override
            public void onDataReceived(byte[] bytes) {
                String size = BytesUtils.ByteArrToHex(bytes);
                Log.d(TAG, "sendFileSize: 文件大小接收返回数据" + size);
                if (size.equals("EB90B003FF0D0A")) {
                    Log.d(TAG, "sendFileSize: 发送文件大小成功，开始发送文件内容");
                    sendFileInput("EB90B004");
                }else {
                    Log.e(TAG, "sendFileSize: 发送文件大小失败");
                }
            }

            @Override
            public void onDataSend(byte[] bytes) {
//                ReadFile.writeBytes2File();
            }
        });
    }

    /**
     * 5.发送文件内容
     * @param hex EB90B004
     * @return EB90B004EE0D0A 错误
     * EB90B004FF0D0A 成功
     */
    private void sendFileInput(String hex) {
        try {
            String data = ReadFile.toHexString(is);
            int length = data.length();
            Log.d(TAG, "sendFileInput: 读取文件内容的长度为" + length);
            mPortHelper.sendHex(hex + data);
            Log.d(TAG, "sendFileInput: " + hex + data);
            mPortHelper.setISerialPortDataListener(new ISerialPortDataListener() {
                @Override
                public void onDataReceived(byte[] bytes) {
                    String sendFile = BytesUtils.ByteArrToHex(bytes);
                    Log.d(TAG, "sendFileInput: 文件内容接收返回数据" + sendFile);
                    if (sendFile.equals("EB90B004FF0D0A")) {
                        Log.d(TAG, "sendFileInput: 发送文件内容成功，通知下位机跳转");
                        informIntentApp("EB90B0050D0A");
                    }else if(sendFile.equals("EB90B004EE0D0A")) {
                        Log.e(TAG, "sendFileInput: 发送文件内容失败");
                    }
                }

                @Override
                public void onDataSend(byte[] bytes) {

                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 6.通知下位机跳转到app层，延时3秒向下位机询问是否跳转成功
     * @param hex EB90B0050D0A
     */
    private void informIntentApp(String hex) {
        mPortHelper.sendHex(hex);
        Log.d(TAG, "informIntentApp: 发送跳转app数据" + hex);
//        mPortHelper.setISerialPortDataListener(new ISerialPortDataListener() {
//            @Override
//            public void onDataReceived(byte[] bytes) {
//                String app = BytesUtils.ByteArrToHex(bytes);
//                Log.d(TAG, "informIntentApp: 返回app层接收返回数据" + app);
//                if (app.equals("")) {
//                    Log.d(TAG, "informIntentApp: 返回app层成功，再次握手");
//                    sendFileSize("EB90B003");
//                }else {
//                    Log.e(TAG, "informIntentApp: 返回app失败");
//                }
//            }
//
//            @Override
//            public void onDataSend(byte[] bytes) {
//
//            }
//        });
        new Thread(() -> {
            try {
                Log.d(TAG, "Thread: 增加三秒延时");
                Thread.sleep(3000);
                isIntentApp("EB90A0020D0A");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
    }

    /**
     * 二次握手，向下位机询问是否跳转成功
     * @param hex  EB90A0020D0A
     * @return EB90A002FF0D0A
     */
    private void isIntentApp(String hex) {
        mPortHelper.sendHex(hex);
        Log.d(TAG, "isIntentApp: 询问是否跳转数据" + hex);
        mPortHelper.setISerialPortDataListener(new ISerialPortDataListener() {
            @Override
            public void onDataReceived(byte[] bytes) {
                String isIntentApp = BytesUtils.ByteArrToHex(bytes);
                Log.d(TAG, "isIntentApp: 检查下位机是否跳转接收返回数据" + isIntentApp);
                if (isIntentApp.equals("EB90A002FF0D0A")) {
                    Log.d(TAG, "isIntentApp: 下位机跳转成功，与下位机通信结束");
                    runOnUiThread(() -> {
                        binding.tvResult.setText("与下位机通信结束啦");
                    });
                }else {
                    Log.e(TAG, "isIntentApp: 下位机跳转失败");
                }
            }

            @Override
            public void onDataSend(byte[] bytes) {

            }
        });
    }
    @Override
    public void insertUsb(UsbDevice device_add) {
        Toast.makeText(this, "检测到U盘插入", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void removeUsb(UsbDevice device_remove) {
        Toast.makeText(this, "检测到U盘已被拔出", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void getReadUsbPermission(UsbDevice usbDevice) {
        
    }

    @Override
    public void failedReadUsb(UsbDevice usbDevice) {
        Toast.makeText(this, "读取U盘失败，请确认是否有权限", Toast.LENGTH_SHORT).show();
    }


    @Override
    public void setUDiskStatus(String msg) {
        binding.tvMsg.setText(msg);
    }

    @Override
    public void setUDiskList(ArrayList<UsbFile> usbFiles) {
        if (usbFiles.size() == 0) {
            binding.tvUdisk.setText("");
        }else {
            String usbName = "";
            for (int i = 0; i < usbFiles.size(); i++) {
                UsbFile usbFile = usbFiles.get(i);
                String name = usbFile.getName();
                usbName = usbName + name + "\n";
                if (usbFile.getAbsolutePath().equals("/nucleicAcid.bin")) {
                    is = new UsbFileInputStream(usbFile);
                    fileLength = new Long(usbFile.getLength()).intValue();
                    Log.d(TAG, "setUDiskList: " + fileLength);
                }
            }
            binding.tvUdisk.setText(usbName);
        }
    }
}